// -*-mode:c++; coding:utf-8-*-

#ifndef _XBASE_ASYNC_WRITE_HPP_
#define _XBASE_ASYNC_WRITE_HPP_

#include <boost/bind.hpp>
#include <boost/system/error_code.hpp>

#include "session.hpp"
#include "protocol.hpp"
#include "session_manager.hpp"

namespace xbase
{
	namespace detail
	{
		struct async_write_helper
		{
			typedef session_manager::endpoint_type endpoint_type;
			typedef session::handler_type handler_type;

			session_manager &m_manager;
			handler_type m_handler;
			protocol::packet_ptr m_packet;
			
			async_write_helper(session_manager &m,
					   handler_type handler,
					   protocol::packet_ptr p)
				: m_manager(m)
				, m_handler(handler)
				, m_packet(p) {}
			
			typedef void result_type;
			
			void operator()(session_ptr s,
					const boost::system::error_code &ec) {
				if(ec)
				{
					m_manager.get_upper_level_service().dispatch(boost::bind(m_handler,
												 protocol::packet_ptr(),
												 ec));
				}
				else
				{
					s->async_write(m_packet,
						       m_manager.get_upper_level_service().wrap(m_handler));
				}
			}
		};
	} // namespace detail
	
	// 通过session_manager直接发送消息，使用户的回调函数将在
	// session_manager的upper_level service上运行。（如果分两步，即
	// 获取连接、发送消息，则用户的第二个回调函数通常是在session的
	// 上层服务上运行）
	inline
	void async_write(session_manager &manager,
			 const session_manager::endpoint_type &ep,
			 protocol::packet_ptr packet,
			 detail::async_write_helper::handler_type handler)
	{
		detail::async_write_helper helper(manager, handler, packet);
		manager.async_connect(ep, helper);
	}

} // namespace xbase

#endif	// _XBASE_ASYNC_WRITE_HPP_
